#include "wx/wxprec.h"

#if wxUSE_FILEDLG

#include "wx/filedlg.h"
#include "wx/dirdlg.h"

#ifndef WX_PRECOMP
#include "wx/string.h"
#include "wx/intl.h"
#include "wx/window.h"
#endif // WX_PRECOMP

IMPLEMENT_DYNAMIC_CLASS( wxFileDialogBase, wxDialog )

void wxFileDialogBase::Init() {
  m_filterIndex =
    m_windowStyle = 0;
}

bool wxFileDialogBase::Create( wxWindow *parent, const wxString& message, const wxString& defaultDir,
                               const wxString& defaultFile, const wxString& wildCard, long style,
                               const wxPoint & ( pos ),const wxSize & ( sz ),const wxString & ( name ) ) {
  m_message = message;
  m_dir = defaultDir;
  m_fileName = defaultFile;
  m_wildCard = wildCard;
  m_parent = parent;
  m_windowStyle = style;
  m_filterIndex = 0;
  if( !HasFdFlag( wxFD_OPEN ) && !HasFdFlag( wxFD_SAVE ) ) {
    m_windowStyle |= wxFD_OPEN;
  }
  wxASSERT_MSG( !( HasFdFlag( wxFD_SAVE ) && HasFdFlag( wxFD_OPEN ) ), _T( "不能同时指定 wxFD_SAVE 和 wxFD_OPEN" ) );
  wxASSERT_MSG( !HasFdFlag( wxFD_SAVE ) || ( !HasFdFlag( wxFD_MULTIPLE ) && !HasFdFlag( wxFD_FILE_MUST_EXIST ) ),
                _T( "wxFD_MULTIPLE 或 wxFD_FILE_MUST_EXIST 不能一起使用在 wxFD_SAVE" ) );
  wxASSERT_MSG( !HasFdFlag( wxFD_OPEN ) || !HasFdFlag( wxFD_OVERWRITE_PROMPT ),
                _T( "wxFD_OVERWRITE_PROMPT 不能使用在 wxFD_OPEN" ) );
  if( wildCard.empty() || wildCard == wxFileSelectorDefaultWildcardStr ) {
    m_wildCard = wxString::Format( _( "All files (%s)|%s" ),
                                   wxFileSelectorDefaultWildcardStr,
                                   wxFileSelectorDefaultWildcardStr );
  } else {
    if( m_wildCard.Find( wxT( '|' ) ) == wxNOT_FOUND ) {
      wxString::size_type nDot = m_wildCard.find( _T( "*." ) );
      if( nDot != wxString::npos ) {
        nDot++;
      } else
      { nDot = 0; }
      m_wildCard = wxString::Format( _( "%s files (%s)|%s" ), wildCard.c_str() + nDot, wildCard.c_str(), wildCard.c_str() );
    }
  }
  return true;
}

long wxFileDialogBase::GetStyle() const {
  return GetWindowStyle();
}

void wxFileDialogBase::SetStyle( long style ) {
  SetWindowStyle( style );
}

wxString wxFileDialogBase::AppendExtension( const wxString &filePath, const wxString &extensionList ) {
  wxString fileName = filePath.AfterLast( wxFILE_SEP_PATH );
  int idx_dot = fileName.Find( wxT( '.' ), true );
  if( ( idx_dot != wxNOT_FOUND ) && ( idx_dot < ( int )fileName.length() - 1 ) ) {
    return filePath;
  }
  wxString ext = extensionList.BeforeFirst( wxT( ';' ) );
  int idx_ext_dot = ext.Find( wxT( '.' ), true );
  if( ( idx_ext_dot == wxNOT_FOUND ) || ( idx_ext_dot == ( int )ext.length() - 1 ) ) {
    return filePath;
  } else
  { ext = ext.AfterLast( wxT( '.' ) ); }
  if( ( ext.Find( wxT( '*' ) ) != wxNOT_FOUND ) ||
      ( ext.Find( wxT( '?' ) ) != wxNOT_FOUND ) ||
      ( ext.Strip( wxString::both ).empty() ) ) {
    return filePath;
  }
  if( filePath.Last() != wxT( '.' ) ) {
    ext = wxT( "." ) + ext;
  }
  return filePath + ext;
}

wxString wxFileSelector( const wxChar *title, const wxChar *defaultDir, const wxChar *defaultFileName,
                         const wxChar *defaultExtension, const wxChar *filter, int flags, wxWindow *parent, int x, int y ) {
  wxString filter2;
  if( !wxIsEmpty( defaultExtension ) && wxIsEmpty( filter ) ) {
    filter2 = wxString( wxT( "*." ) ) + defaultExtension;
  } else if( !wxIsEmpty( filter ) ) {
    filter2 = filter;
  }
  wxString defaultDirString;
  if( !wxIsEmpty( defaultDir ) ) {
    defaultDirString = defaultDir;
  }
  wxString defaultFilenameString;
  if( !wxIsEmpty( defaultFileName ) ) {
    defaultFilenameString = defaultFileName;
  }
  wxFileDialog fileDialog( parent, title, defaultDirString,
                           defaultFilenameString, filter2,
                           flags, wxPoint( x, y ) );
  if( ( wxStrlen( defaultExtension ) != 0 ) && ( filter2.Find( wxT( '|' ) ) != wxNOT_FOUND ) ) {
    int filterIndex = 0;
    wxArrayString descriptions, filters;
    ( void )wxParseCommonDialogsFilter( filter2, descriptions, filters );
    for( size_t n = 0; n < filters.GetCount(); n++ ) {
      if( filters[n].Contains( defaultExtension ) ) {
        filterIndex = n;
        break;
      }
    }
    if( filterIndex > 0 ) {
      fileDialog.SetFilterIndex( filterIndex );
    }
  }
  wxString filename;
  if( fileDialog.ShowModal() == wxID_OK ) {
    filename = fileDialog.GetPath();
  }
  return filename;
}

wxString wxFileSelectorEx( const wxChar *title, const wxChar *defaultDir, const wxChar *defaultFileName,
                           int* defaultFilterIndex, const wxChar *filter, int flags, wxWindow* parent, int x, int y )

{
  wxFileDialog fileDialog( parent, !wxIsEmpty( title ) ? title : wxEmptyString,
                           !wxIsEmpty( defaultDir ) ? defaultDir : wxEmptyString,
                           !wxIsEmpty( defaultFileName ) ? defaultFileName : wxEmptyString,
                           !wxIsEmpty( filter ) ? filter : wxEmptyString, flags, wxPoint( x, y ) );
  wxString filename;
  if( fileDialog.ShowModal() == wxID_OK ) {
    if( defaultFilterIndex ) {
      *defaultFilterIndex = fileDialog.GetFilterIndex();
    }
    filename = fileDialog.GetPath();
  }
  return filename;
}

static wxString wxDefaultFileSelector( bool load, const wxChar *what, const wxChar *extension, const wxChar *default_name,
                                       wxWindow *parent ) {
  wxString prompt;
  wxString str;
  if( load ) {
    str = _( "Load %s file" );
  } else
  { str = _( "Save %s file" ); }
  prompt.Printf( str, what );
  wxString wild;
  const wxChar *ext = extension;
  if( !wxIsEmpty( ext ) ) {
    if( *ext == wxT( '.' ) ) {
      ext++;
    }
    wild.Printf( wxT( "*.%s" ), ext );
  } else // no extension specified
  { wild = wxFileSelectorDefaultWildcardStr; }
  return wxFileSelector( prompt, NULL, default_name, ext, wild,
                         load ? ( wxFD_OPEN | wxFD_FILE_MUST_EXIST ) : wxFD_SAVE, parent );
}

wxString wxLoadFileSelector( const wxChar *what,
                             const wxChar *extension,
                             const wxChar *default_name,
                             wxWindow *parent ) {
  return wxDefaultFileSelector( true, what, extension, default_name, parent );
}

wxString wxSaveFileSelector( const wxChar *what,
                             const wxChar *extension,
                             const wxChar *default_name,
                             wxWindow *parent ) {
  return wxDefaultFileSelector( false, what, extension, default_name, parent );
}

long wxDirDialogBase::GetStyle() const {
  return GetWindowStyle();
}

void wxDirDialogBase::SetStyle( long style ) {
  SetWindowStyle( style );
}


#endif // wxUSE_FILEDLG
